package com.leyou.item.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper;
import com.leyou.common.constants.RocketMQConstants;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.RocketMQConstants.TAGS.ITEM_DOWN_TAGS;
import static com.leyou.common.constants.RocketMQConstants.TAGS.ITEM_UP_TAGS;
import static com.leyou.common.constants.RocketMQConstants.TOPIC.ITEM_TOPIC_NAME;

@Service
public class GoodsService {

    @Autowired
    private TbSpuService tbSpuService;
    /**
     * 分页查询spu信息
     * @param page
     * @param rows
     * @param key
     * @param saleable
     * @return
     */
    public PageResult<SpuDTO> findSpuByPage(Integer page, Integer rows, String key, Boolean saleable) {

//        构造分页条件
        Page<TbSpu> page1 = new Page<>(page,rows);
//        构造查询条件
        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper<>();
        if(!StringUtils.isBlank(key)){
            queryWrapper.lambda().like(TbSpu::getName,key);
        }
        if(saleable != null){
            queryWrapper.lambda().eq(TbSpu::getSaleable,saleable);
        }
        IPage<TbSpu> tbSpuIPage = tbSpuService.page(page1,queryWrapper);
        if(tbSpuIPage == null || CollectionUtils.isEmpty(tbSpuIPage.getRecords())){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(tbSpuIPage.getRecords(), SpuDTO.class);
//         查询 分类的名字和品牌的名字
        handlerCategoryNameAndBrandName(spuDTOList);
        return new PageResult<SpuDTO>(spuDTOList,tbSpuIPage.getPages(),tbSpuIPage.getTotal());
    }

    @Autowired
    private TbBrandService tbBrandService;
    @Autowired
    private TbCategoryService tbCategoryService;

    private void handlerCategoryNameAndBrandName(List<SpuDTO> spuDTOList) {
        for (SpuDTO spuDTO : spuDTOList) {
            Long brandId = spuDTO.getBrandId();
//            查询品牌对象
            TbBrand tbBrand = tbBrandService.getById(brandId);
            String brandName = tbBrand.getName();
            spuDTO.setBrandName(brandName);

//          根据id集合 获取 对象的集合
            Collection<TbCategory> tbCategories = tbCategoryService.listByIds(spuDTO.getCategoryIds());
//            使用遍历生成拼接后的 分类名称
//            String categoryName = "";
//            for (TbCategory tbCategory : tbCategories) {
//                if(categoryName.length()>0){
//                    categoryName += "/";
//                }
//                categoryName += tbCategory.getName();
//            }
//          使用流获取名称
            String categoryName = tbCategories.stream()
                    .map(TbCategory::getName)
                    .collect(Collectors.joining("/"));

            spuDTO.setCategoryName(categoryName);
        }
    }

    @Autowired
    private TbSpuDetailService tbSpuDetailService;
    @Autowired
    private TbSkuService tbSkuService;
    /**
     * 保存商品
     * 3张表
     * tb_spu tb_spu_detail tb_sku
     * @param spuDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveGoods(SpuDTO spuDTO) {
//      对象转换
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
//        保存spu
        boolean b = tbSpuService.save(tbSpu);
        if(!b){
           throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
//        获取spu的主键id
        Long spuId = tbSpu.getId();
//        转换构造tb对象
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDetailDTO, TbSpuDetail.class);
        tbSpuDetail.setSpuId(spuId);
//        保存detail
        boolean b1 = tbSpuDetailService.save(tbSpuDetail);
        if(!b1){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
//        获取sku的集合
        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        if(CollectionUtils.isEmpty(skuDTOList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
//        对象转换
        List<TbSku> tbSkuList = BeanHelper.copyWithCollection(skuDTOList, TbSku.class);
//        设置spuid
        for (TbSku tbSku : tbSkuList) {
            tbSku.setSpuId(spuId);
        }
//        保存sku
        boolean b2 = tbSkuService.saveBatch(tbSkuList);
        if(!b2){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     * 修改上下架操作
     * @param spuId
     * @param saleable
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateSaleable(Long spuId, Boolean saleable) {
        TbSpu tbSpu = new TbSpu();
        tbSpu.setId(spuId);
        tbSpu.setSaleable(saleable);
//        修改spu的saleable
        boolean b = tbSpuService.updateById(tbSpu);
        if(!b){
           throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//        update tb_sku set enable=? where spu_id=?
        UpdateWrapper<TbSku> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().
                eq(TbSku::getSpuId,spuId).
                set(TbSku::getEnable,saleable);
//        修改sku的enable
        boolean b1 = tbSkuService.update(updateWrapper);
        if(!b1){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//        设定tags的内容
        String tags = saleable ? ITEM_UP_TAGS : ITEM_DOWN_TAGS;
//        设置topic和tags的内容
        String dest = ITEM_TOPIC_NAME+ ":"+ tags;
//        上下架操作成功，发送RocketMQ消息,消息内容 是 spuid
        rocketMQTemplate.convertAndSend(dest,spuId);
    }

    /**
     * 根据spuid 查询spudetail对象
     * @param spuId
     * @return
     */
    public SpuDetailDTO findSpuDetailBySpuId(Long spuId) {

        TbSpuDetail tbSpuDetail = tbSpuDetailService.getById(spuId);
        if(tbSpuDetail == null){
            throw new LyException(ExceptionEnum.GOODS_DETAIL_NOT_FOUND);
        }
        return BeanHelper.copyProperties(tbSpuDetail,SpuDetailDTO.class);
    }

    /**
     * 根据spuid 查询sku集合
     * @param spuId
     * @return
     */
    public List<SkuDTO> findSkuListBySpuId(Long spuId) {
//        构造查询条件
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId,spuId);
        List<TbSku> tbSkuList = tbSkuService.list(queryWrapper);
        if(CollectionUtils.isEmpty(tbSkuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(tbSkuList,SkuDTO.class);
    }

    /**
     * 修改商品信息
     * 修改3张表
     * @param spuDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateGoods(SpuDTO spuDTO) {

        /*
        * 测试呵呵哈哈哈
        *
        *
        * */
        Long spuId = spuDTO.getId();
//        对象转换
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
//        更新spu表
        boolean b = tbSpuService.updateById(tbSpu);
        if(!b){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        if(spuDTO.getSpuDetail() == null){
            throw new LyException(ExceptionEnum.GOODS_DETAIL_NOT_FOUND);
        }
//        对象转换
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), TbSpuDetail.class);
//        更新spuDetail表
        boolean b1 = tbSpuDetailService.updateById(tbSpuDetail);
        if(!b1){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//        delete from tb_sku where spu_id = ?
//        构造查询条件
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId,spuId);
//        删除sku表的数据，根据spuId
        boolean b2 = tbSkuService.remove(queryWrapper);
        if(!b2){
            throw new LyException(ExceptionEnum.DELETE_OPERATION_FAIL);
        }
//        获取sku的集合
        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        if(CollectionUtils.isEmpty(skuDTOList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
//        对象转换
        List<TbSku> tbSkuList = BeanHelper.copyWithCollection(skuDTOList, TbSku.class);
//        设置spuid
        for (TbSku tbSku : tbSkuList) {
            tbSku.setSpuId(spuId);
        }
//        新增sku表的数据
        boolean b3 = tbSkuService.saveBatch(tbSkuList);
        if(!b3){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /**
     * 根据主键id查询spu对象
     * @param spuId
     * @return
     */
    public SpuDTO findSpuById(Long spuId) {
        TbSpu tbSpu = tbSpuService.getById(spuId);
        if(tbSpu == null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(tbSpu,SpuDTO.class);
    }

    /**
     * 根据id集合查询sku的集合
     * @param skuIds
     * @return
     */
    public List<SkuDTO> findSkuListByIds(List<Long> skuIds) {
        Collection<TbSku> tbSkuCollection = tbSkuService.listByIds(skuIds);
        if(CollectionUtils.isEmpty(tbSkuCollection)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        List<TbSku> tbSkuList = (List<TbSku>) tbSkuCollection;

        return BeanHelper.copyWithCollection(tbSkuList,SkuDTO.class);
    }

    /**
     * 减库存操作
     * @param skuIdNumMap
     */
    @Transactional(rollbackFor = Exception.class)
    public void minusStock(Map<Long, Integer> skuIdNumMap) {
//      select stock from tb_sku where id=?
//        update tb_sku   set  stock=stock-#{num}  where  id = #{id}
        for (Long skuId : skuIdNumMap.keySet()) {
            Integer num = skuIdNumMap.get(skuId);
            int code = tbSkuService.minusStock(skuId,num);
            if(code < 1){
                throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }

    }

    /**
     * 恢复库存
     * @param skuIdNumMap
     */
    @Transactional(rollbackFor = Exception.class)
//    update tb_sku   set  stock=stock+#{num}  where  id = #{id}
    public void plusStock(Map<Long, Integer> skuIdNumMap) {
        for (Long skuId : skuIdNumMap.keySet()) {
            Integer num = skuIdNumMap.get(skuId);
            int code = tbSkuService.plusStock(skuId,num);
            if(code < 1){
                throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }
    }

    /**
     * 根据brandId查询商品列表
     *
     * @param brandId
     * @param cid3
     * @return
     */
    public List<SpuDTO> findSpuByBrandId(Long brandId, Long cid3) {
        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSpu::getBrandId, brandId).eq(TbSpu::getCid3, cid3);
        List<TbSpu> tbSpuList = tbSpuService.list(queryWrapper);
        return BeanHelper.copyWithCollection(tbSpuList, SpuDTO.class);
    }
}
